"""API请求授权中间件"""

import logging
from typing import Optional, Union, Callable
from fastapi import Request, HTTPException, Depends
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from starlette.status import HTTP_401_UNAUTHORIZED, HTTP_403_FORBIDDEN

from backend.common.config import config_manager
from backend.middleware.trace_middleware import get_trace_id
from backend.logger_setup import get_logger_with_trace_id

logger = logging.getLogger('middleware.auth')
security = HTTPBearer()

class AuthMiddleware:
    """API请求授权中间件"""
    
    def __init__(self, app):
        self.app = app
    
    async def __call__(self, scope, receive, send):
        # 仅处理HTTP请求
        if scope['type'] != 'http':
            await self.app(scope, receive, send)
            return
        
        # 创建请求对象
        request = Request(scope, receive)
        
        # 获取trace_id
        trace_id = get_trace_id(request)
        
        # 获取带trace_id的logger
        log = get_logger_with_trace_id(logger, trace_id)
        
        # 获取路径
        path = request.url.path
        
        # 检查是否需要跳过授权
        if self._should_skip_auth(path):
            await self.app(scope, receive, send)
            return
        
        try:
            # 执行授权检查
            user_info = await self._authenticate_request(request)
            
            # 将用户信息添加到请求状态中
            scope['user'] = user_info
            
            # 继续处理请求
            await self.app(scope, receive, send)
        except HTTPException as e:
            log.warning(f"授权失败 [trace_id={trace_id}, path={path}]: {e.detail}")
            # 返回错误响应
            from fastapi.responses import JSONResponse
            response = JSONResponse(
                status_code=e.status_code,
                content={
                    "error": "Unauthorized",
                    "detail": e.detail,
                    "trace_id": trace_id
                }
            )
            await response(scope, receive, send)
        except Exception as e:
            log.error(f"授权过程异常 [trace_id={trace_id}, path={path}]: {str(e)}")
            # 返回500错误
            from fastapi.responses import JSONResponse
            response = JSONResponse(
                status_code=500,
                content={
                    "error": "Internal Server Error",
                    "detail": "Authentication process failed",
                    "trace_id": trace_id
                }
            )
            await response(scope, receive, send)
    
    def _should_skip_auth(self, path: str) -> bool:
        """检查是否需要跳过授权
        
        Args:
            path: 请求路径
            
        Returns:
            是否跳过授权
        """
        # 直接使用硬编码的默认公共路径列表，不依赖于config_manager.auth属性
        public_paths = [
            '/api/v1/sessions',
            '/api/v1/tools',
            '/api/health',
            '/api/metrics',
            '/docs',
            '/redoc',
            '/openapi.json'
        ]
        public_prefixes = [
            '/api/v1/sessions/',
            '/api/v1/llm/ollama/',
            '/api/v1/datasets/'
        ]
        
        # 检查路径是否在免授权列表中
        for public_path in public_paths:
            if path == public_path or path == public_path.rstrip('/') or path.rstrip('/') == public_path:
                return True
        
        for prefix in public_prefixes:
            if path.startswith(prefix):
                return True
        
        # 健康检查接口免授权
        if path.endswith('/health') or path.endswith('/metrics'):
            return True
        
        # 静态文件免授权
        if path.startswith('/static/'):
            return True
        
        return False
    
    async def _authenticate_request(self, request: Request) -> dict:
        """验证请求的授权信息
        
        Args:
            request: FastAPI请求对象
            
        Returns:
            用户信息字典
            
        Raises:
            HTTPException: 授权失败时抛出
        """
        try:
            # 获取授权配置
            auth_config = config_manager.auth
        except AttributeError:
            # 如果配置中没有auth属性，默认允许访问（因为我们在本地开发环境中）
            return {
                "user_id": "anonymous",
                "role": "guest",
                "auth_type": "none"
            }
        
        # 简易模式：使用API密钥
        if auth_config.mode == 'simple':
            # 从请求头中获取API密钥
            api_key = request.headers.get('X-API-Key')
            
            # 如果没有提供API密钥，尝试从查询参数中获取
            if not api_key:
                api_key = request.query_params.get('api_key')
            
            # 验证API密钥
            if not api_key or api_key != auth_config.api_key:
                raise HTTPException(
                    status_code=HTTP_401_UNAUTHORIZED,
                    detail="Invalid or missing API key"
                )
            
            # 返回用户信息
            return {
                "user_id": "api_user",
                "role": "user",
                "auth_type": "api_key"
            }
        
        # JWT模式
        elif auth_config.mode == 'jwt':
            # 这里应该实现JWT验证逻辑
            # 由于当前没有完整的JWT验证系统，返回示例用户信息
            # 实际实现时需要替换为真实的JWT验证逻辑
            try:
                credentials: HTTPAuthorizationCredentials = await security(request)
                token = credentials.credentials
                
                # 验证token（这里仅作示例）
                if not token or token != 'dummy-jwt-token':
                    raise HTTPException(
                        status_code=HTTP_401_UNAUTHORIZED,
                        detail="Invalid or missing JWT token"
                    )
                
                # 返回用户信息
                return {
                    "user_id": "jwt_user",
                    "role": "user",
                    "auth_type": "jwt",
                    "token": token
                }
            except Exception:
                raise HTTPException(
                    status_code=HTTP_401_UNAUTHORIZED,
                    detail="Invalid or missing JWT token",
                    headers={"WWW-Authenticate": "Bearer"}
                )
        
        # 未配置授权模式
        else:
            # 默认允许访问（本地开发环境）
            return {
                "user_id": "anonymous",
                "role": "guest",
                "auth_type": "none"
            }

def get_current_user(request: Request) -> dict:
    """从请求中获取当前用户信息
    
    Args:
        request: FastAPI请求对象
        
    Returns:
        用户信息字典
    """
    if hasattr(request.state, 'user'):
        return request.state.user
    
    # 如果请求状态中没有用户信息，返回匿名用户
    return {
        "user_id": "anonymous",
        "role": "guest",
        "auth_type": "none"
    }

def admin_required(current_user: dict = Depends(get_current_user)):
    """管理员权限验证依赖
    
    Args:
        current_user: 当前用户信息
        
    Raises:
        HTTPException: 没有管理员权限时抛出
    """
    # 检查用户角色是否为管理员
    if current_user.get('role') != 'admin':
        raise HTTPException(
            status_code=HTTP_403_FORBIDDEN,
            detail="Admin permission required"
        )
    
    return current_user

def setup_auth(app):
    """设置应用的授权中间件
    
    Args:
        app: FastAPI应用实例
    """
    # 注册授权中间件
    app.add_middleware(AuthMiddleware)

__all__ = [
    'AuthMiddleware',
    'get_current_user',
    'admin_required',
    'setup_auth'
]
